package com.ljy.my_study.java8.CompletableFuture;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/** 
* @author James
* @date 2018年11月29日 
*/
public class TestMain {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
//		test1();
//		test2();
		test3();
	}
	
	private static void test1() throws InterruptedException, ExecutionException {
		CompletableFuture<String> future=new CompletableFuture<>();
		new Thread(()-> {
			System.out.println("task doing...");
			try {
				Thread.sleep(3_000);
//				int i=1/0;//这里报异常，线程结束，不过外面的future.get()获取不到结果，会一直阻塞
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			future.complete("ok");
		}).start(); 
		String result=future.get();
		System.out.println("result is:"+result);
	}
	
	private static void test2() throws InterruptedException, ExecutionException {
		CompletableFuture<String> future=new CompletableFuture<>();
		new Thread(()-> {
			System.out.println("task doing...");
			try {
				Thread.sleep(3_000);
				int i=1/0;
			} catch (Exception e) {
				future.completeExceptionally(e);
			}
			future.complete("ok");
		}).start(); 
		String result=future.get();
		System.out.println("result is:"+result);
	}
	
	private static void test3() {
		long start=System.currentTimeMillis();
		List<String> resultList=new ArrayList<>();
		ExecutorService executor=Executors.newFixedThreadPool(10);
		List<Integer> taskList=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
		
		CompletableFuture[] cfs = taskList.stream()
                .map(integer -> CompletableFuture.supplyAsync(() -> calc(integer), executor)
                                .thenApply(h->Integer.toString(h))
                                //s是结果，e是异常
                                .whenComplete((s, e) -> {
                                    System.out.println("任务"+s+"完成!result="+s+"，异常 e="+e+","+new Date());
                                    resultList.add(s);
                                })
                ).toArray(CompletableFuture[]::new);
		CompletableFuture.allOf(cfs).join();
//		CompletableFuture.anyOf(cfs).join();
		System.out.println("resultList="+resultList+"，耗时："+(System.currentTimeMillis()-start));
		executor.shutdown();
	}
	
	private static int calc(int i) {
		try {
			if(i==1) {
				Thread.sleep(5_000);
			}else if(i==5) {
				Thread.sleep(3_000);
			}else {
				Thread.sleep(1_000);
			}
			System.out.println("task线程："+Thread.currentThread().getName()+"，任务i="+i+"完成，时间："+new Date());
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		return i;
	}
}
